package com.xy.async.listener;

import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.util.Assert;

import com.xy.async.handler.HandlerService;
import com.xy.async.handler.context.AsyncContext;
import com.xy.async.strategy.StrategyFactory;

import lombok.extern.slf4j.Slf4j;

/**
 * 事件监听
 *
 *  
 * @date 2022/3/2
 */
@Slf4j
@Component
public class AsyncListener {

    /**
     * TransactionalEventListener是对EventListener的增强，
     * 被注解的方法可以在事务的不同阶段去触发执行，如果事件未在激活的事务中发布，
     * 除非显式设置了 fallbackExecution() 标志为true，否则该事件将被丢弃；
     * 如果事务正在运行，则根据其 TransactionPhase 处理该事件。
     */

    /**
     * 处理事件 <br>
     * fallbackExecution=true 没有事务正在运行，依然处理事件,不然事件不会处理 <br>
     * TransactionPhase.AFTER_COMPLETION 事务提交，事务回滚都处理事件
     *
     * AFTER_COMMIT - 默认设置，在事务提交后执行
     * AFTER_ROLLBACK - 在事务回滚后执行
     * AFTER_COMPLETION - 在事务完成后执行（不管是否成功）
     * BEFORE_COMMIT - 在事务提交前执行
     * 
     * @param context
     *
     * AsyncAspect <----------------- PUBLISH
     *
     */
    @TransactionalEventListener(fallbackExecution = true, phase = TransactionPhase.AFTER_COMPLETION)
    public void asyncHandler(AsyncContext context) throws InterruptedException {
        log.info("Listener start");
        Thread.sleep(3000);
        HandlerService handlerService = StrategyFactory.doStrategy(context.getAsyncExec().type().name(), HandlerService.class);
        Assert.notNull(handlerService, "异步执行策略不存在");
        handlerService.handle(context);
    }

}
